﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Prometheus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;

namespace Helpers
{
    public static class PrometheusHelperExtensions
    {
        private static MetricPusher _metricPusher;
        /// <summary>
        /// 开启MetricPusher,自动添加ip:port标签
        /// </summary>
        public static async Task<IApplicationBuilder> UseMetricPusherHelper(this IApplicationBuilder app, MetricPusherOptions options)
        {
            try
            {
                if (_metricPusher == null)
                {
                    var features = app.Properties["server.Features"] as FeatureCollection;
                    var port = new Uri(features.Get<IServerAddressesFeature>()
                        .Addresses
                        .FirstOrDefault().Replace("*", "0.0.0.0")).Port;

                    string host = null;
                    try
                    {
                        using var client = new HttpClient(new HttpClientHandler { AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate });
                        client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36");
                        var jj = await (await client.GetAsync("https://ip.cn/api/index?ip=&type=0").ConfigureAwait(false)).Content.ReadAsStringAsync().ConfigureAwait(false);
                        var j = JsonConvert.DeserializeObject<JObject>(jj);
                        host = j.Value<string>("ip");
                    }
                    catch (Exception)
                    {
                        NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces(); //适配器
                        host = adapters
                            .Where(x => x.Name == "eth0" || x.Name.Contains("以太网"))
                            .Select(p => p.GetIPProperties())
                            .SelectMany(p => p.UnicastAddresses)
                            .Where(p => p.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !System.Net.IPAddress.IsLoopback(p.Address))
                            .Select(x => x.Address.ToString())
                            .FirstOrDefault();
                    }

                    var ip = $"{host}:{port}";

                    if (string.IsNullOrWhiteSpace(options.Instance))
                    {
                        options.Instance = ip;
                    }
                    else
                    {
                        List<Tuple<string, string>> list = options.AdditionalLabels == null ? new List<Tuple<string, string>>() : new List<Tuple<string, string>>(options.AdditionalLabels);
                        if (!options.AdditionalLabels.Any(x => x.Item1 == "ip"))
                        {
                            list.Add(new Tuple<string, string>("ip", ip));
                        }
                        options.AdditionalLabels = list;
                    }
                    _metricPusher = new MetricPusher(options);
                    _metricPusher.Start();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("UseMetricPusherHelper异常--" + ex.Message);
            }
            return app;
        }
    }
}
